﻿using iMaoTai.Api.Core;

using Microsoft.Extensions.Caching.Memory;

public class MainService : ITransient
{
    private readonly ILogger<MainService> _logger;
    private readonly RequestService _requestService;
    private readonly IMemoryCache _memoryCache;
    private string _cacheKey = "MtSessionId";

    public MainService(ILogger<MainService> logger, RequestService requestService, IMemoryCache memoryCache)
    {
        _logger = logger;
        _requestService = requestService;
        _memoryCache = memoryCache;
    }

    #region 本地库查询

    /// <summary>
    /// 门店列表
    /// </summary>
    /// <returns></returns>
    public PageDto GetShopList(ParamsDto paramsDto)
    {
        using (var db = DbContext.Instance.GetConnection(DbContext.Default_DB))
        {
            int total = 0;
            PageDto pageDto = new PageDto() { pageIndex = paramsDto.pageIndex, pageSize = paramsDto.pageSize };
            var list = db.Queryable<ShopEntity>()
                .WhereIF(!string.IsNullOrEmpty(paramsDto.keyword), o => o.CompanyName.Contains(paramsDto.keyword) || o.Name.Contains(paramsDto.keyword))
                .WhereIF(!string.IsNullOrEmpty(paramsDto.province), o => o.Province.Contains(paramsDto.province))
                .WhereIF(!string.IsNullOrEmpty(paramsDto.city), o => o.City.Contains(paramsDto.city))
                .WhereIF(!string.IsNullOrEmpty(paramsDto.area), o => o.Area.Contains(paramsDto.area))
                .Distinct()
                .ToPageList(paramsDto.pageIndex, paramsDto.pageSize, ref total);
            pageDto.total = total;
            pageDto.data = list;
            return pageDto;
        }
    }

    /// <summary>
    /// 省份下拉框
    /// </summary>
    /// <returns></returns>
    public List<string> GetProvinceSelect()
    {
        using (var db = DbContext.Instance.GetConnection(DbContext.Default_DB))
        {
            var list = db.Queryable<ShopEntity>().Select(o => o.Province)
                .Distinct()
                .ToList();

            return list;
        }
    }

    /// <summary>
    /// 城市下拉框
    /// </summary>
    /// <returns></returns>
    public List<string> GetCitySelect(string province)
    {
        using (var db = DbContext.Instance.GetConnection(DbContext.Default_DB))
        {
            var list = db.Queryable<ShopEntity>().Where(o => o.Province == province).Select(o => o.City)
                .Distinct()
                .ToList();

            return list;
        }
    }

    /// <summary>
    /// 人员列表
    /// </summary>
    /// <returns></returns>
    public PageDto GetUserList(ParamsDto paramsDto)
    {
        using (var db = DbContext.Instance.GetConnection(DbContext.Default_DB))
        {
            int total = 0;
            PageDto pageDto = new PageDto() { pageIndex = paramsDto.pageIndex, pageSize = paramsDto.pageSize };
            var list = db.Queryable<UserEntity>()
                 .WhereIF(!string.IsNullOrEmpty(paramsDto.keyword), o => o.Mobile.Contains(paramsDto.keyword))
                 .Where(o => o.IsDelete != 1)
                 .ToPageList(paramsDto.pageIndex, paramsDto.pageSize, ref total);
            pageDto.total = total;
            pageDto.data = list;
            return pageDto;
        }
    }

    /// <summary>
    /// 日志列表
    /// </summary>
    /// <returns></returns>
    public PageDto GetLogList(ParamsDto paramsDto)
    {
        using (var db = DbContext.Instance.GetConnection(DbContext.Default_DB))
        {
            int total = 0;
            PageDto pageDto = new PageDto() { pageIndex = paramsDto.pageIndex, pageSize = paramsDto.pageSize };
            var list = db.Queryable<LogEntity>()
                 .WhereIF(!string.IsNullOrEmpty(paramsDto.keyword), o => o.MobilePhone.Contains(paramsDto.keyword))
                 .OrderByDescending(o => o.Id)
                 .ToPageList(paramsDto.pageIndex, paramsDto.pageSize, ref total);
            pageDto.total = total;

            var list2 = GetProductList(new ParamsDto { pageIndex = 1, pageSize = 200 });
            List<ProductEntity> productList = list2.data;
            foreach (var item in list)
            {
                if (item.Content.Contains("[shopId]"))
                {
                    var array = item.Content.Split("[shopId]:");
                    if (array.Length > 1)
                    {
                        item.ItemCode = array[1];
                        item.Picture = productList.FirstOrDefault(o => o.itemCode == item.ItemCode).picture;
                    }
                }
            }
            pageDto.data = list;
            return pageDto;
        }
    }

    #endregion 本地库查询

    #region 商品

    /// <summary>
    /// 查询
    /// </summary>
    /// <param name="paramsDto"></param>
    /// <returns></returns>

    public PageDto GetProductList(ParamsDto paramsDto)
    {
        using (var db = DbContext.Instance.GetConnection(DbContext.Default_DB))
        {
            int total = 0;
            PageDto pageDto = new PageDto() { pageIndex = paramsDto.pageIndex, pageSize = paramsDto.pageSize };
            var list = db.Queryable<ProductEntity>()
                 .OrderByDescending(o => o.itemCode)
                 .ToPageList(paramsDto.pageIndex, paramsDto.pageSize, ref total);
            pageDto.total = total;
            pageDto.data = list;
            return pageDto;
        }
    }

    /// <summary>
    /// 更新商品
    /// </summary>
    /// <returns></returns>
    public async Task AddOrUpdateProductAsync()
    {
        using (var db = DbContext.Instance.GetConnection(DbContext.Default_DB))
        {
            db.Ado.BeginTran();
            var list = await _requestService.GetRequestProductList();

            db.Deleteable<ProductEntity>().ExecuteCommand();
            db.Insertable(list).ExecuteCommand();

            db.Ado.CommitTran();
        }
    }

    #endregion 商品

    #region 门店

    /// <summary>
    /// 更新门店
    /// </summary>
    /// <returns></returns>
    public async Task AddOrUpdateShopAsync()
    {
        using (var db = DbContext.Instance.GetConnection(DbContext.Default_DB))
        {
            db.Ado.BeginTran();
            var list = await _requestService.GetRequestShopList();

            db.Deleteable<ShopEntity>().ExecuteCommand();
            db.Insertable(list).ExecuteCommand();

            db.Ado.CommitTran();
        }
    }

    #endregion 门店

    #region 预约

    public async Task<dynamic> ReservationBatch(string mobile = "")
    {
        List<UserEntity> userList = GetUserList(new ParamsDto { pageIndex = 1, pageSize = 200 }).data;

        if (!string.IsNullOrEmpty(mobile))
        {
            userList = userList.Where(o => o.Mobile == mobile).ToList();
        }

        foreach (var user in userList)
        {
            var items = user.ItemCode.Split("@");

            foreach (var item in items)
            {
                var shopId = await GetShopId(user, item);
                if (!string.IsNullOrEmpty(shopId))
                {
                    var logEntity = await _requestService.Reservation(user, item, shopId);
                    if (logEntity != null)
                    {
                        using (var db = DbContext.Instance.GetConnection(DbContext.Default_DB))
                        {
                            db.Insertable(logEntity).ExecuteCommand(); ;
                        }
                    }
                }
            }
        }

        return "预约成功";
    }

    private async Task<string> GetShopId(UserEntity user, string item)
    {
        var shopList = await _requestService.GetShopsByProvince(user.ProvinceName, item);
        var shopIdList = shopList.Select(i => i.ShopId).ToList();
        List<ShopEntity> iShops = GetShopList(new ParamsDto { pageIndex = 1, pageSize = 100000 }).data;
        //// 获取今日的门店信息列表
        var filteredShop = iShops.Where(i => shopIdList.Contains(i.ShopId)).ToList();

        var shopId = "";
        if (user.ShopType == 1)
        {
            // 预约本市出货量最大的门店
            shopId = GetMaxInventoryShopId(shopList, filteredShop, user.CityName);
            if (string.IsNullOrEmpty(shopId))
            {
                // 本市没有则预约本省最近的
                shopId = GetMinDistanceShopId(filteredShop, user.ProvinceName, user.Lat, user.Lng);
            }
        }

        if (user.ShopType == 2)
        {
            // 预约本省距离最近的门店
            shopId = GetMinDistanceShopId(filteredShop, user.ProvinceName, user.Lat, user.Lng);
        }
        return shopId;
    }

    /// <summary>
    /// 预约本市出货量最大的门店
    /// </summary>
    /// <param name="shopIdList">  </param>
    /// <param name="filteredShop"></param>
    /// <param name="cityName">    </param>
    /// <returns></returns>
    private string GetMaxInventoryShopId(List<IMTItemInfo> shopIdList, List<ShopEntity> filteredShop, string cityName)
    {
        // 本城市的shopId集合
        var cityShopIdList = filteredShop.Where(i => i.City.Contains(cityName)).Select(i => i.ShopId)
            .ToList();

        var collect = shopIdList.Where(i => cityShopIdList.Contains(i.ShopId)).ToList();
        collect.Sort((a, b) => b.Inventory.CompareTo(a.Inventory));
        if (collect.Count > 0) return collect[0].ShopId;
        return null;
    }

    /// <summary>
    /// 预约本省距离最近的门店
    /// </summary>
    /// <param name="filteredShop"></param>
    /// <param name="provinceName"></param>
    /// <param name="lat">         </param>
    /// <param name="lng">         </param>
    /// <returns></returns>
    private string GetMinDistanceShopId(List<ShopEntity> filteredShop, string provinceName, string lat, string lng)
    {
        var iShopList = filteredShop.Where(i => i.Province.Contains(provinceName)).ToList();
        var mapPoint = new MapPointDto(double.Parse(lat), double.Parse(lng));
        foreach (var storeEntity in iShopList)
        {
            var point = new MapPointDto(double.Parse(storeEntity.Lat), double.Parse(storeEntity.Lng));
            storeEntity.Distance = GetDistance(mapPoint, point);
        }
        var minDistance = iShopList.Min(i => i.Distance);
        var shopId = iShopList.FirstOrDefault(i => i.Distance == minDistance)?.ShopId;
        return shopId;
    }

    /// <summary>
    /// 获取两个点之间的距离
    /// </summary>
    /// <param name="point1"></param>
    /// <param name="point2"></param>
    /// <returns></returns>
    private static double GetDistance(MapPointDto point1, MapPointDto point2)
    {
        var lat1 = (point1.Latitude * Math.PI) / 180; //将角度换算为弧度
        var lat2 = (point2.Latitude * Math.PI) / 180; //将角度换算为弧度
        var latDifference = lat1 - lat2;
        var lonDifference = (point1.Longitude * Math.PI) / 180 - (point2.Longitude * Math.PI) / 180;
        //计算两点之间距离   6378137.0 取自WGS84标准参考椭球中的地球长半径(单位:m)
        return 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(latDifference / 2), 2)
                                       + Math.Cos(lat1) * Math.Cos(lat2) * Math.Pow(Math.Sin(lonDifference / 2), 2))) * 6378137.0;
    }

    #endregion 预约

    #region 用户管理

    /// <summary>
    /// </summary>
    /// <returns></returns>
    public async Task Login(string mobile, string code)
    {
        using (var db = DbContext.Instance.GetConnection(DbContext.Default_DB))
        {
            db.Ado.BeginTran();
            var user = await _requestService.Login(mobile, code);

            var oldUser = GetUserInfo(mobile);
            if (oldUser != null)
            {
                user.Lng = oldUser.Lng;
                user.Lat = oldUser.Lat;
                user.ProvinceName = oldUser.ProvinceName;
                user.CityName = oldUser.CityName;
                user.ShopType = oldUser.ShopType;
                db.Updateable(user).ExecuteCommand();
            }
            else
            {
                db.Insertable(user).ExecuteCommand();
            }
            //db.Deleteable<ProductEntity>(user).ExecuteCommand();

            db.Ado.CommitTran();
        }
    }

    /// <summary>
    /// 用户明细
    /// </summary>
    /// <param name="mobile"></param>
    /// <returns></returns>
    public UserEntity GetUserInfo(string mobile)
    {
        List<UserEntity> userList = GetUserList(new ParamsDto { pageIndex = 1, pageSize = 200 }).data;
        var user = userList.Where(o => o.Mobile == mobile).FirstOrDefault();
        return user;
    }

    /// <summary>
    /// 删除
    /// </summary>
    /// <returns></returns>
    public void DeleteUser(string mobile)
    {
        using (var db = DbContext.Instance.GetConnection(DbContext.Default_DB))
        {
            db.Ado.BeginTran();
            var user = GetUserInfo(mobile);
            user.IsDelete = 1;
            db.Updateable(user).ExecuteCommand();

            db.Ado.CommitTran();
        }
    }

    /// <summary>
    /// 更新
    /// </summary>
    /// <returns></returns>
    public void UpdateUser(UpdateUserInput input)
    {
        using (var db = DbContext.Instance.GetConnection(DbContext.Default_DB))
        {
            var user = GetUserInfo(input.mobile);
            user.ProvinceName = input.provinceName;
            user.CityName = input.cityName;
            user.ItemCode = string.Join("@", input.itemCode);
            user.ShopType = input.shopType;
            List<ShopEntity> shopList = GetShopList(new ParamsDto { pageIndex = 1, pageSize = 100000 }).data;
            var shop = shopList.Where(o => o.Province == input.provinceName && o.City == input.cityName).FirstOrDefault();
            user.Lat = shop.Lat;
            user.Lng = shop.Lng;
            db.Updateable(user).ExecuteCommand();
        }
    }

    #endregion 用户管理
}